package com.qf.bigdata.util;

import org.ujmp.core.DenseMatrix;
import org.ujmp.core.Matrix;
import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

public class Leastsq {


    //y=ax^b
    //lny=lna+blnx
    //f=lny,theta0=lna,g=lnx,b=theta1
    //f=theta0+theta1*g
    //求解theta矩阵  :(X^TX)^(-1)X^TY
    public static Matrix matrixSolve(List<Sample> samples) {

        //创建一个矩阵
        Matrix matrixX=DenseMatrix.Factory.ones(samples.size(),2);
        Matrix matrixY=DenseMatrix.Factory.ones(samples.size(),1);
        for (int i = 0; i < samples.size(); i++) {
            matrixX.setAsDouble(samples.get(i).getX(),i,1);
            matrixY.setAsDouble(samples.get(i).getY(),i,0);
        }
		
        //X^T
        Matrix matrixXTranspose = matrixX.transpose();
        //X^TX
        Matrix matrixXTransposeTtimes = matrixXTranspose.mtimes(matrixX);
        //(X^TX)^(-1)
        Matrix matrixXTransposeTtimesInv = matrixXTransposeTtimes.inv();
        //(X^TX)^(-1)X^T
        Matrix mtimes = matrixXTransposeTtimesInv.mtimes(matrixXTranspose);
        //(X^TX)^(-1)X^TY
        Matrix theta = mtimes.mtimes(matrixY);
        /*
        Matrix ones = DenseMatrix.Factory.ones(2, 2);

        Matrix zeros=DenseMatrix.Factory.zeros(2, 2);
        zeros.setAsDouble(1,0,0);
        zeros.setAsDouble(2,0,1);
        zeros.setAsDouble(3,1,0);
        zeros.setAsDouble(4,1,1);

        Matrix mtimes = zeros.mtimes(zeros);


        Matrix transpose = mtimes.transpose();

        Matrix inv = transpose.inv();
*/
        return theta;
    }

    public static void main(String[] args) {
        //f=theta0+theta1*g
        //x->g  y->f
        //g=lnx,f=lny
        List<Sample> samples=new ArrayList<>();
        samples.add(new Sample(Math.log(1),Math.log(0.5)));
        samples.add(new Sample(Math.log(2),Math.log(0.4)));
        samples.add(new Sample(Math.log(3),Math.log(0.3)));
        Matrix theta=matrixSolve(samples);
        double theta0=theta.getAsDouble(0,0);
        double theta1=theta.getAsDouble(1,0);

        //a,b   =>  theta0=lna,b=theta1
        double a=Math.pow(Math.E,theta0);
        double b=theta1;



        System.out.println("y="+a+"x^"+b);

        //第100日留存率是多少？
        System.out.println(a*Math.pow(100,b));
		
        //假定每日新增是1000，100日DAU是多少？
        double rr=0.0;
        for (int i=1;i<=100;i++){
            double temp=(a*(Math.pow(i,b)));
            rr+=temp;
        }
		
        System.out.println(rr);
        System.out.println(1000*(1+rr));

    }
}
